<?php
/**
 * test case for Webappkit class
 * @author J.Ducastel <jeremie@ducastel.name>
 * @todo lasy-loading related tests
 */
class TestWebappkit extends UnitTestCase {

	/*function TestWebappkit() {
		$this->UnitTestCase('Testing Webappkit class');

		// $this->kit=webappkit::getKit('webappkit/tests');
		// $this->assertIsA($this->kit,'webappkit');
	}*/

	/**
	 * here we use the webappkit tests kit itself as an exemple kit
	 */
	function setUp() {

	}

	function tearDown() {

	}

	/**
	* @todo mergeArrays
	* @todo isVersionWithinRange
	* @todo listKits
	*/
	function testUtilities() {
		$this->assertEqual(Webappkit::cmpVersionStrings('5.2.7','5.2.7'),0,"5.2.7 = 5.2.7");
		$this->assertEqual(Webappkit::cmpVersionStrings('5.2.*','5.2.7'),0,"5.2.* = 5.2.7");
		$this->assertEqual(Webappkit::cmpVersionStrings('5.*','5.2.7'),0);
		$this->assertEqual(Webappkit::cmpVersionStrings('5.2','4.2.9'),1);
		$this->assertEqual(Webappkit::cmpVersionStrings('4.2.9','5.2.7'),-1);
		$this->assertEqual(Webappkit::cmpVersionStrings('5.2.5','5.2'),1);
		$this->assertEqual(Webappkit::cmpVersionStrings('3.*','3.*'),0);
	}


	function testStaticMethods() {
		try {
		$this->assertIsA(Webappkit::timecounter(),'float',"timecounter doesn't return a float");

		$this->assertTrue(Webappkit::checkKit('webappkit.testkit'));
		$this->assertFalse(Webappkit::checkKit('i/do/not/exist'));

		$this->assertIsA(Webappkit::checkId('webappkit.testkit'),'string');
		$this->assertFalse(Webappkit::checkId('with spaces'));
		} catch (Exception $e) {
			$this->fail("Exception should not have been raised with checkKit and checkId : ".$e->getMessage());
		}

		// version string
	}

	function testGetPathFromId() {
		$path=Webappkit::getPathFromId('webappkit.testkit');
		$this->assertIsA($path,'string',"path ($path) is not a string");
		$this->assertTrue(file_exists($path),"invalid path returned ($path)");
		// exceptions
		try {
			$path=Webappkit::getPathFromId('webappkit.testkit.nokit');
			$this->fail("getPathFromId should raise WakBadKit when bad id");
		} catch (WakBadKit $e) {
			$this->pass();
		} catch (Exception $e) {
			$this->fail("getPathFromId should raise WakBadKit when bad id");
		}
	}

	function testGetCfgFromId() {
		$cfg=Webappkit::getCfgFromId('webappkit.testkit');
		$this->assertIsA($cfg,'array',"config is not an array");
		$this->assertIsA($cfg['kit']['version'],'string',"no kit version in cfg");
		// exceptions
		try {
			$cfg=Webappkit::getCfgFromId('webappkit.testkit.badkit1');
			$this->fail("getCfgFromId shoudl raise WakBadCfg when no/bad cfg");
		} catch (WakBadCfg $e) {
			$this->pass();
		} catch (Exception $e) {
			$this->fail("getCfgFromId shoudl raise WakBadCfg when no/bad cfg");
		}
		try {
			$cfg=Webappkit::getCfgFromId('webappkit.testkit.badkit5');
			$this->fail("getCfgFromId shoudl raise WakBadCfg when no/bad cfg");
		} catch (WakBadCfg $e) {
			$this->pass();
		} catch (Exception $e) {
			$this->fail("getCfgFromId should raise WakBadCfg when no/bad cfg");
		}
	}

	// should be before testlibkit
	function testGetKit() {
		try {
			$kit=&Webappkit::getKit('webappkit.testkit');
			// class
			$this->assertIsA($kit,'RunKit',"testkit should have custom RunKit class");
			// loaded subkits
			// deactivated because admin loads kits+subkits at the moment, for diagnostics
			//$this->assertFalse(class_exists('someclass'),"SHOULD NOT have loaded optional subkit");
			// tools
			$this->assertIsA($kit->test,'WakTool',"testkit should have a 'test' tool");
		} catch (Exception $e) {
			$this->fail("should not have raised exception at this point");
		}

		// exceptions
		try {
			Webappkit::getKit('i am not a kit');
			Webappkit::getKit('i/am/not/a/kit/either');
			$this->fail("getkit should raise a WakBadKit exception on invalid ids");
		} catch (WakBadKit $e) {
			$this->pass("getkit should raise a WakBadKit exception on invalid ids");
		}
		try {
			// wak.ini missing
			Webappkit::getKit('webappkit.testkit.badkit1');
			$this->fail("getkit should raise WakBadCfg if wak.ini is missing");
		} catch (WakBadCfg $e) {
			$this->pass();
		}
		try {
			// kit class missing
			Webappkit::getKit('webappkit.testkit.badkit2');
			$this->fail("getkit should raise WakBadKit if kit class is missing");
		} catch (WakBadKit $e) {
			$this->pass();
		}
		try {
			// kit class not extending webappkit
			Webappkit::getKit('webappkit.testkit.badkit3');
			$this->fail("getkit should raise WakBadKit if kit class dont extend webappkit");
		} catch (WakBadKit $e) {
			$this->pass();
		}
		// missing kits
		try {
			Webappkit::loadKit('webappkit.testkit.badkit4');
			$this->fail("loadkit should raise WakMissingKit if kit requires missing kits");
		} catch (WakMissingKit $e) {
			$this->pass();
		}
		// missing files
		try {
			Webappkit::loadKit('webappkit.testkit.badkit6');
			$this->fail("loadkit should raise WakMissingFile if kit requires missing files");
		} catch (WakMissingFile $e) {
			$this->pass();
		}
	}

	function testLibKit() {
		try  {
			$version=Webappkit::loadKit('webappkit.testkit.libkit');
			$this->assertIsA($version,'string',"loadKit should return version loaded. %s");

			// checking loaded files
			$this->assertTrue(class_exists('someclass'),"should have loaded someclass library file");
			$this->assertEqual(SomeClass::php(),5);

			// testing run
			$kit=Webappkit::getKit('webappkit.testkit.libkit');
			$kit->run();
			$this->fail("kit->run should raise WakNotImplemented by default");
		} catch (WakNotImplemented $e) {
			$this->pass("kit->run should raise WakNotImplemented by default");
		} catch (Exception $e) {
			$this->fail($e->getMessage());
		}

	}

	function testConstructor() {
		$kit=&Webappkit::getkit('webappkit.testkit');
		$this->assertIsA($kit,'WakKit');

		$kit2=&Webappkit::getkit('webappkit.testkit');
		$this->assertReference($kit,$kit2,"Kits should be singletons ! %s");

		$kit3=&Webappkit::getkit('webappkit/testkit');
		$this->assertReference($kit,$kit3,"Kits should be singletons, using both / or dot level separators ! %s");

		// checking class

		// checking tools

		// $this->expectError();
	}

	function testInstanceMethods() {
		$id='webappkit.testkit';
		try {

			$kit=&Webappkit::getkit($id);

			$this->assertEqual($kit->getId(),$id);

			$path=$kit->getPath($id);
			$this->assertIsA($path,'string',"invalid path %s");
			$this->assertTrue(file_exists($path),"path doesn't exist. ($path)");

			$this->assertIsA($kit->getCfg(),'array');
		} catch (Exception $e) {
			$this->fail($e->getMessage());
		}
	}

	/**
	 * webappkit.testkit should have 2 tools
	 */
	function testGetTools() {
		$id='webappkit.testkit';
		try {

			$kit=&Webappkit::getkit($id);
			$tools=$kit->getTools();
			$this->assertEqual(count($tools),2
				,"webappkit.testkit have 2 tools that should be returned by getTools()");
			$this->assertIsA($tools['test'],'WakTool'
				,"getTools() shall return an associative array of instances");
			// filtering
			$tools=$kit->getTools('WakStorage');
			$this->assertEqual(count($tools),1
				,"getTools(of_class) shall return only tools of specified class");
			$this->assertIsA($tools['teststorage'],'WakStorage'
				,"getTools() shall return an associative array of instances");
			// $this->dump($kit);
		} catch (Exception $e) {
			$this->fail($e->getMessage());
		}
	}

	function testExceptions() {



	}

	/*function testFail() {
		$this->assertTrue(false);
		$this->assertError();
		$this->assertTrue(trigger_error("une erreur"));
	}*/

}
